//
//  VideoRecordVC.m
//  Test
//
//  Created by fh on 2021/11/17.
//  Copyright © 2021 cashchina. All rights reserved.
//

#import "VideoRecordVC.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <Photos/Photos.h>

#import <Masonry/Masonry.h>
#import "StudioRecordTool.h"
#import "StudioAuthorizationTool.h"
#import "AuthorizationView.h"

@interface VideoRecordVC ()
/// 显示摄像头采集画面
@property (nonatomic, strong) UIView *videoShowView;
/// 返回按钮按钮
@property (nonatomic, strong) UIButton *backButton;
/// 切换摄像头按钮
@property (nonatomic, strong) UIButton *changeDeviceButton;
/// 结束录制按钮
@property (nonatomic, strong) UIButton *endRecordButton;
/// 录制时长标签
@property (nonatomic, strong) UILabel *recordTimeLabel;
/// 视频大小
@property (nonatomic, strong) UILabel *videoSizeLabel;

/** 媒体采集工具 */
@property (nonatomic, strong) StudioRecordTool *recordTool;
/** 设备授权视图 */
@property (nonatomic, strong) AuthorizationView *authorizationView;
/** 是否应该隐藏电池栏 */
@property (nonatomic, assign) BOOL shouldHiddenStatusBar;
/** 照片和视频是否支持保存到相册:默认YES */
@property (nonatomic, assign) BOOL isSavedPhotosAlbum;
@end

@implementation VideoRecordVC

#pragma mark - Life cycle
- (void)viewDidLoad {
    [super viewDidLoad];
    [self requestForAuthorization];
}
- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    [self.recordTool configurePreviewWithView:self.videoShowView frame:self.videoShowView.bounds];
}

#pragma mark - Private
- (void)setupData {
    self.isSavedPhotosAlbum = YES;
}

- (void)requestForAuthorization {
    __weak typeof(self) weakSelf = self;
    [StudioAuthorizationTool asyncJudgeAvailableWithCamera:^(BOOL cameraIsAvailable, BOOL cameraIsManual, NSString *cameraAvailableInfo) {
        if (cameraIsAvailable) {
        
            [StudioAuthorizationTool asyncJudgeAvailableWithMic:^(BOOL micIsAvailable, BOOL micIsManual, NSString *micAvailableInfo) {
                if (micIsAvailable) {
                    weakSelf.shouldHiddenStatusBar = YES;
                    [weakSelf prepareVideoRecordView];
                }else if (!micIsAvailable && micIsManual) {
                    weakSelf.shouldHiddenStatusBar = NO;
                    [weakSelf dismissViewControllerAnimated:YES completion:nil];
                }else if (!micIsAvailable && !micIsManual) {
                    weakSelf.shouldHiddenStatusBar = NO;
                    weakSelf.authorizationView.authorizationInfoLabel.text = @"温馨提示\n\n请在iPhone的\"设置-隐私\"选项中,允许该应用程序访问您的麦克风";
                    [weakSelf.view addSubview:weakSelf.authorizationView];
                    [weakSelf.authorizationView mas_remakeConstraints:^(MASConstraintMaker *make) {
                        make.left.right.equalTo(@(0));
                        make.center.equalTo(weakSelf.view);
                    }];
                }
            }];
            
        }else if (!cameraIsAvailable && cameraIsManual) {
            weakSelf.shouldHiddenStatusBar = NO;
            [weakSelf dismissViewControllerAnimated:YES completion:nil];
        }else if (!cameraIsAvailable && !cameraIsManual) {
            if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
                weakSelf.shouldHiddenStatusBar = NO;
                weakSelf.authorizationView.authorizationInfoLabel.text = @"温馨提示\n\n请在iPhone的\"设置-隐私\"选项中,允许该应用程序访问您的摄像头";
                [weakSelf.view addSubview:weakSelf.authorizationView];
                [weakSelf.authorizationView mas_remakeConstraints:^(MASConstraintMaker *make) {
                    make.left.right.equalTo(@(0));
                    make.center.equalTo(weakSelf.view);
                }];
            } else {
                weakSelf.shouldHiddenStatusBar = NO;
                /*
                [weakSelf showLoadingWithRemindText:@"温馨提示\n授权失败,相机设备无法使用"];
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [weakSelf hiddenLoadingRemindText];
                    [weakSelf dismissViewControllerAnimated:YES completion:nil];
                });
                //*/
            }
        }
    }];
}

/**
 配置视频录制界面和视频录制功能
 */
- (void)prepareVideoRecordView {
    __weak typeof(self) weakSelf = self;
    // 初始化控制器数据
    [self setupData];
    // 绘制UI
    [self setupView];
//    [self testSetupView];
    /// 初始化视频录制功能
    self.recordTool = [[StudioRecordTool alloc] initDefaultVideo];
    // 使用系统方式设置视频输出压缩质量
//    self.recordTool.configuration.videoConfigurationMode = SCVideoConfigurationModeOutputSettingsAssistant;
//    self.recordTool.configuration.videoOutputSettingsPreset = SCOutputSettingsPreset1920x1080;
    
    /*
    self.recordTool.configuration.videoAverageBitRate = (350 * 1000); // 视频码率:bits/s,只支持H.264编码
    self.recordTool.configuration.videoExpectedSourceFrameRate = 20; // 帧速率:单位->帧/秒,即fps,高于30帧/秒设置该值
    
    self.recordTool.configuration.videoCodecType = SCVideoCodecTypeH264; // 视频编码类型
    self.recordTool.configuration.videoWidth = 960; // 视频宽
    self.recordTool.configuration.videoHeight = 960; // 视频高
    self.recordTool.configuration.videoScalingMode = SCVideoScalingModeResizeAspectFill; // 平铺方式
    self.recordTool.configuration.videoPixelAspectRatio = SCVideoPixelAspectRatioMake(1, 1); // 画面像素比例,设置后根据像素比居中按比例截取画面,
//    self.recordTool.configuration.videoProfileLevel = SCVideoProfileLevelH264Main32; //视频压缩标准
    self.recordTool.configuration.videoMaxKeyFrameInterval = 2; // 关键帧之间的最大间隔,也称为关键帧速率:1表示关键帧,只支持H.264编码 ;关键帧最大间隔，1为每个都是关键帧，数值越大压缩率越高
    self.recordTool.configuration.videoMaxKeyFrameIntervalDuration = 300; // 从一个关键帧到下一个关键帧的最大持续时间，以秒为单位:默认为0,这意味着没有限制,只支持H.264编码
//    self.recordTool.configuration.videoAverageNonDroppableFrameRate = YES; // 启用或禁用帧重新排序,默认YES,由编码器决定是否启用帧重排序
//    self.recordTool.configuration.videoAverageNonDroppableFrameRate = 20; // 为每秒的视频编码所需的非可丢弃帧的平均数量
    
//    self.recordTool.configuration.sessionPreset = SCCaptureSessionPreset1920x1080; // 采集画面分辨率，会话分辨率
    
    //*/
    
    {
        self.recordTool.configuration.videoAverageBitRate = [StudioConfiguration shareInstanceConfiguration].videoAverageBitRate;
        self.recordTool.configuration.videoExpectedSourceFrameRate = [StudioConfiguration shareInstanceConfiguration].videoExpectedSourceFrameRate;
        
        self.recordTool.configuration.videoWidth = [StudioConfiguration shareInstanceConfiguration].videoWidth; // 视频宽
        self.recordTool.configuration.videoHeight = [StudioConfiguration shareInstanceConfiguration].videoHeight; // 视频高
    }
    
    /// 覆盖保存
    self.recordTool.coverStoreVideo = NO;
//    /// 视频录制模式最大变焦
//    self.videoRecordView.minScaleAndCropFactor = self.recordTool.photoMinScaleAndCropFactor;
//    /// 视频录制模式最大变焦
//    self.videoRecordView.maxScaleAndCropFactor = self.recordTool.photoMaxScaleAndCropFactor;
    
    // 视频被打断事件回调(除了切到后台的事件,app切换到后台的事件单独处理)
    self.recordTool.videoRecordWasInterruptedBlock = ^(NSInteger interruptedReason) {
//        [weakSelf dismissViewControllerAnimated:YES completion:nil];
    };
    
    // app切换到后台自动结束录制视频
    self.recordTool.videoRecordDidEnterBackgroundWasInterruptedBlock = ^(NSURL *outputFileURL, NSError *videoRecordError, int videoDuration, float videoSize) {
        
    };
    
    [self startRecordVideo];

}

/// 绘制UI
- (void)setupView {
    __weak typeof(self) weakSelf = self;
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.backButton];
    [self.view addSubview:self.videoShowView];
    [self.view addSubview:self.changeDeviceButton];
    [self.view addSubview:self.endRecordButton];
    [self.view addSubview:self.recordTimeLabel];
    [self.view addSubview:self.videoSizeLabel];
    
    [self.backButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.top.left.equalTo(@(20));
        make.height.equalTo(@(40));
        make.width.equalTo(@(80));
    }];
    [self.videoShowView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(weakSelf.backButton.mas_bottom).offset(64);
        make.width.equalTo(weakSelf.view.mas_width);
        make.height.equalTo(weakSelf.videoShowView.mas_width);
    }];
    [self.changeDeviceButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.bottom.right.equalTo(@(-20));
        make.height.equalTo(@(40));
        make.width.equalTo(@(80));
    }];
    [self.endRecordButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(@(20));
        make.bottom.equalTo(@(-20));
        make.height.equalTo(@(40));
        make.width.equalTo(@(80));
    }];
    [self.recordTimeLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(weakSelf.view.mas_centerX);
        make.top.equalTo(weakSelf.videoShowView.mas_bottom).offset(10);
    }];
    
    [self.videoSizeLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(weakSelf.videoShowView.mas_centerX);
        make.top.equalTo(weakSelf.recordTimeLabel.mas_bottom).offset(10);
    }];
    
}

/// 开始录制
- (void)startRecordVideo {
    [self.recordTool beginCapture];
    [self.recordTool startVideoRecord];
    __weak typeof(self) weakSelf = self;
    [self.recordTool watchVideoRecordProcessWithBlock:^(CGFloat processTime) {
        [weakSelf updateVideoRecordTimeStrWithVideoProcessTime:processTime];
    }];
}

/**
 更新录制时间

 @param processTime 录制时间
 */
- (void)updateVideoRecordTimeStrWithVideoProcessTime:(CGFloat)processTime {
    NSInteger houri = (NSInteger)processTime / 60 / 60;
    NSInteger mini = (NSInteger)processTime / 60;
    NSInteger seci = (NSInteger)processTime % 60;
    NSString *recordTime = [NSString stringWithFormat:@"%.2ld:%.2ld:%.2ld",houri, mini,seci];
    self.recordTimeLabel.text = recordTime;
//    NSLog(@"%@",recordTime);
}

- (UIColor *)colorFromHex:(int)hex {
    return [UIColor colorWithRed:((float)((hex & 0xFF0000) >> 16))/255.0 green:((float)((hex & 0xFF00) >> 8))/255.0 blue:((float)(hex & 0xFF))/255.0 alpha:1.0];
}


/******************************************************************************************************************/
// test private
// test UI
- (void)testSetupView {
    __weak typeof(self) weakSelf = self;
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *beginCaptureButton = [self createTestButtonWithTitle:@"采集" action:@selector(testBeginCaptureButtonAction:)];
    UIButton *endCaptureButton = [self createTestButtonWithTitle:@"停止采集" action:@selector(testEndCaptureButtonAction:)];\
    UIButton *recordButton = [self createTestButtonWithTitle:@"录制" action:@selector(testRecordButtonAction:)];
    UIButton *endRecordButton = [self createTestButtonWithTitle:@"停止录制" action:@selector(testEndRecordButtonAction:)];
    UIButton *changeButton = [self createTestButtonWithTitle:@"切换摄像头" action:@selector(testChangeDeviceButtonAction:)];
    
    [self.view addSubview:self.videoShowView];
    [self.view addSubview:beginCaptureButton];
    [self.view addSubview:endCaptureButton];
    [self.view addSubview:recordButton];
    [self.view addSubview:endRecordButton];
    [self.view addSubview:changeButton];
    [self.view addSubview:self.recordTimeLabel];
    [self.view addSubview:self.videoSizeLabel];
    
    [self.videoShowView mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(@(64));
        make.width.equalTo(weakSelf.view.mas_width);
        make.height.equalTo(weakSelf.videoShowView.mas_width);
    }];
    
    [self.recordTimeLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(weakSelf.videoShowView.mas_centerX);
        make.top.equalTo(weakSelf.videoShowView.mas_bottom).offset(10);
    }];
    
    [self.videoSizeLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(weakSelf.videoShowView.mas_centerX);
        make.top.equalTo(weakSelf.recordTimeLabel.mas_bottom).offset(10);
    }];
    
    [beginCaptureButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(weakSelf.videoSizeLabel.mas_bottom).offset(10);
        make.left.equalTo(@(10));
        make.height.equalTo(@(30));
    }];
    [endCaptureButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(beginCaptureButton.mas_centerY);
        make.left.equalTo(beginCaptureButton.mas_right).offset(15);
        make.height.equalTo(@(30));
    }];
    [recordButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(beginCaptureButton.mas_centerY);
        make.left.equalTo(endCaptureButton.mas_right).offset(15);
        make.height.equalTo(@(30));
    }];
    [endRecordButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(beginCaptureButton.mas_centerY);
        make.left.equalTo(recordButton.mas_right).offset(15);
        make.height.equalTo(@(30));
    }];
    [changeButton mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(beginCaptureButton.mas_centerY);
        make.left.equalTo(endRecordButton.mas_right).offset(15);
        make.height.equalTo(@(30));
    }];

}

- (UIButton *)createTestButtonWithTitle:(NSString *)title action:(SEL)action {
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setTitle:title forState:UIControlStateNormal];
    button.titleLabel.font = [UIFont systemFontOfSize:15];
    button.backgroundColor = [self colorFromHex:0xd61d41];
//    button.layer.cornerRadius = 5;
    [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
    return button;
}

// test action
- (void)testBeginCaptureButtonAction:(UIButton *)button {
    // 开启摄像头采集画面
    [self.recordTool beginCapture];
}
- (void)testEndCaptureButtonAction:(UIButton *)button {
    // 停止摄像头采集画面
    [self.recordTool endCapture];
}
- (void)testRecordButtonAction:(UIButton *)button {
    // 开始录制
    [self.recordTool startVideoRecord];
    __weak typeof(self) weakSelf = self;
    [self.recordTool watchVideoRecordProcessWithBlock:^(CGFloat processTime) {
        [weakSelf updateVideoRecordTimeStrWithVideoProcessTime:processTime];
    }];
}
- (void)testChangeDeviceButtonAction:(UIButton *)button {
    // 切换摄像头
    [self.recordTool toggleCamera];
}
- (void)testEndRecordButtonAction:(UIButton *)button {
    // 结束录制
    __weak typeof(self) weakSelf = self;
    
//    [self showLoadingWithRemindText:@"正在处理..."];
    [self.recordTool stopVideoRecordWithAllDetailCompletion:^(NSURL *outputFileURL, UIImage *videoImage, NSError *videoRecordError, int videoDuration, float videoSize) {
//        [weakSelf hiddenLoadingRemindText];
#ifdef DEBUG
        NSLog(@"录制结果: %@ --- 视频截图: %@ --- 录制错误信息: %@ --- 视频时长: %d --- 视频大小: %f",outputFileURL,videoImage,videoRecordError,videoDuration,videoSize);
#endif
        weakSelf.videoSizeLabel.text = [NSString stringWithFormat:@"视频时长: %@ \n视频大小: %@",videoDuration,videoSize];
        
        if (weakSelf.isSavedPhotosAlbum) {
            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(outputFileURL.path)) {
                //保存视频到相册
                UISaveVideoAtPathToSavedPhotosAlbum(outputFileURL.path, weakSelf, @selector(video:didFinishSavingWithError:contextInfo:), nil);
            }
        }
        if (videoDuration > 0) {
//            [weakSelf.videoRecordView previewVideoWithVideoURL:outputFileURL videoImage:videoImage videoDuration:videoDuration videoSize:videoSize];
        }
    }];
}

/******************************************************************************************************************/

#pragma mark - Event
/// 返回事件回调
/// @param button 返回按钮
- (void)backButtonAction:(UIButton *)button {
    [self.recordTool endCapture];
    [self dismissViewControllerAnimated:YES completion:nil];
}

/// 定义视频切换摄像头事件回调
/// @param button 视频摄像头切换按钮
- (void)changeDeviceButtonAction:(UIButton *)button {
    [self.recordTool toggleCamera];
}

- (void)endRecordButtonAction:(UIButton *)button {
    __weak typeof(self) weakSelf = self;
    
//    [self showLoadingWithRemindText:@"正在处理..."];
    [self.recordTool stopVideoRecordWithAllDetailCompletion:^(NSURL *outputFileURL, UIImage *videoImage, NSError *videoRecordError, int videoDuration, float videoSize) {
//        [weakSelf hiddenLoadingRemindText];
#ifdef DEBUG
        NSLog(@"录制结果: %@ --- 视频截图: %@ --- 录制错误信息: %@ --- 视频时长: %d --- 视频大小: %f",outputFileURL,videoImage,videoRecordError,videoDuration,videoSize);
#endif
        
        weakSelf.videoSizeLabel.text = [NSString stringWithFormat:@"视频时长: %ds \n视频大小: %fMB",videoDuration,videoSize];
        
        if (weakSelf.isSavedPhotosAlbum) {
            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(outputFileURL.path)) {
                //保存视频到相册
                UISaveVideoAtPathToSavedPhotosAlbum(outputFileURL.path, weakSelf, @selector(video:didFinishSavingWithError:contextInfo:), nil);
            }
        }
        if (videoDuration > 0) {
//            [weakSelf.videoRecordView previewVideoWithVideoURL:outputFileURL videoImage:videoImage videoDuration:videoDuration videoSize:videoSize];
        }
    }];
}

/**
 取消设备授权处理方法

 @param button 取消授权按钮
 */
- (void)authorizationViewCancleButtonAction:(UIButton *)button {
    [self dismissViewControllerAnimated:YES completion:nil];
}


/**
 保存视频完成之后的回调

 @param videoPath 要保存的视频路径
 @param error 错误信息
 @param contextInfo 上下文信息
 */
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
#ifdef DEBUG
    NSLog(@"保存视频完成之后的线程%@",[NSThread currentThread]);
    if (!error) {
        NSLog(@"视频保存到相册成功");
    }
    NSLog(@"videoPath = %@, error = %@-%@, contextInfo = %@", videoPath, error, error.localizedDescription, contextInfo);
#endif
    if (error) {
        PHAuthorizationStatus authStatus = [PHPhotoLibrary authorizationStatus];
        if (authStatus == PHAuthorizationStatusRestricted|| authStatus == PHAuthorizationStatusDenied) {
//            [self showTipViewWithInfo:@"保存视频到相册失败，请检查相册的访问权限"];
            NSLog(@"保存视频到相册失败，请检查相册的访问权限");
        }else {
//            [self showTipViewWithInfo:error.localizedDescription];
            NSLog(@"%@",error.localizedDescription);
        }
    }
}

#pragma mark - Setter and getter
- (UIView *)videoShowView {
    if (!_videoShowView) {
        _videoShowView = [UIView new];
        _videoShowView.backgroundColor = [UIColor orangeColor];
    }
    return _videoShowView;
}
- (UIButton *)backButton {
    if (!_backButton) {
        _backButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_backButton setTitle:@"返回" forState:UIControlStateNormal];
        [_backButton addTarget:self action:@selector(backButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        _backButton.titleLabel.font = [UIFont systemFontOfSize:15];
        _backButton.backgroundColor = [self colorFromHex:0xd61d41];
        _backButton.layer.cornerRadius = 5;
    }
    return _backButton;
}
- (UIButton *)changeDeviceButton {
    if (!_changeDeviceButton) {
        _changeDeviceButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_changeDeviceButton setTitle:@"切换" forState:UIControlStateNormal];
        [_changeDeviceButton addTarget:self action:@selector(changeDeviceButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        _changeDeviceButton.titleLabel.font = [UIFont systemFontOfSize:15];
        _changeDeviceButton.backgroundColor = [self colorFromHex:0xd61d41];
        _changeDeviceButton.layer.cornerRadius = 5;
    }
    return _changeDeviceButton;
}
- (UIButton *)endRecordButton {
    if (!_endRecordButton) {
        _endRecordButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_endRecordButton setTitle:@"结束" forState:UIControlStateNormal];
        [_endRecordButton addTarget:self action:@selector(endRecordButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        _endRecordButton.titleLabel.font = [UIFont systemFontOfSize:15];
        _endRecordButton.backgroundColor = [self colorFromHex:0xd61d41];
        _endRecordButton.layer.cornerRadius = 5;
    }
    return _endRecordButton;
}
- (AuthorizationView *)authorizationView {
    if (!_authorizationView) {
        _authorizationView = [[AuthorizationView alloc] init];
        [_authorizationView.cancleButton addTarget:self action:@selector(authorizationViewCancleButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _authorizationView;
}
-  (UILabel *)recordTimeLabel {
    if (!_recordTimeLabel) {
        _recordTimeLabel = [UILabel new];
        _recordTimeLabel.font = [UIFont boldSystemFontOfSize:18];
        _recordTimeLabel.textColor = [self colorFromHex:0xd61d41];
        _recordTimeLabel.textAlignment = NSTextAlignmentCenter;
        _recordTimeLabel.text = @"00:00:00";
    }
    return _recordTimeLabel;
}
- (UILabel *)videoSizeLabel {
    if (!_videoSizeLabel) {
        _videoSizeLabel = [UILabel new];
        _videoSizeLabel.font = [UIFont systemFontOfSize:15];
        _videoSizeLabel.textColor = [UIColor whiteColor];
        _videoSizeLabel.textAlignment = NSTextAlignmentCenter;
        _videoSizeLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.75];
        _videoSizeLabel.numberOfLines = 0;
    }
    return _videoSizeLabel;
}
@end
